package com.zzl.test.proxy.dynamicproxy;

import com.gitee.yongzhuzl.commonutil.util.equals.EqualsUtil;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 温馨提示：
 * 动态代理模式:
 * 动态代理类的源码是在程序运行期间通过JVM反射等机制动态生成，
 * 代理类和委托类的关系是运行时才确定的
 *
 * description: 动态代理：代理工厂，给多个目标对象生成代理对象！
 * @author 朱正磊
 * @date 2019-08-09 11:13:33
 */
public class ProxyFactory {

    // 接收一个目标对象（委托对象）
    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    /**
     * description: 获取对目标对象(target)代理后的对象(proxy)
     * @author 朱正磊
     * @date 2019-08-09 11:18:39
     * @return 返回对目标对象(target)代理后的对象(proxy)
     */
    public Object getProxyInstance() {
        // 执行代理对象方法时候触发
        return Proxy.newProxyInstance(
            target.getClass().getClassLoader(), // 目标对象使用的类加载器
            target.getClass().getInterfaces(), // 目标对象实现的所有接口
            (proxy, method, args) -> {
                // 获取当前执行的方法的方法名
                String methodName = method.getName();
                // 方法返回值
                Object result = null;
                if (EqualsUtil.isEquals("find", methodName)) {
                    // 直接调用目标对象方法
                    result = method.invoke(target, args);
                } else if (EqualsUtil.isEquals("save", methodName)) {
                    System.out.println("代理操作：开启事务...");

                    // 执行目标对象方法
                    result = method.invoke(target, args);

                    System.out.println("代理操作：提交事务...");
                }
                return result;
            }
        );
    }

}
